#include "parser.h"
#include "../robocup/datos.h"

using namespace std;
void Parser::leerparentesis(string cad)
{
    int i=0;
    if (cad.compare(1,3,"see")==0 || cad.compare(1,5,"sense")==0)
        i=1; /** Nos evitamos leer el primer parentesis en las cadenas mas largas */
    for(i;i<cad.size();i++)
    {
        if(cad.at(i)=='(')
        {
            inicio.push_back(i);
            for(int j=i+1;j<cad.size();j++)
            {
                if(cad.at(j)=='(')
                {
                    inicio.pop_back(); /** Borramos el ( de inicio anterior, solo nos interesa el ultimo */
                    inicio.push_back(j);
                    while(cad.at(j)!=')')
                        j++;
                    fin1.push_back(j);
                    j++; /* Necesrio para no leer 2 veces la misma posicion*/
                }
                if(cad.at(j)==')')
                {
                    fin2.push_back(j);
                    j++; /* Necesrio para no leer 2 veces la misma posicion*/
                    if (j>=cad.size())
                        i=cad.size()-1; /* Comprobaremos despues la ultima posicion otra vez*/
                    else
                        i=j;
                    break; /* Salimos del segundo bucle for */
                }
            }
        }
        if(cad.at(i)==')')
            fin2.push_back(i);
    }
}

void Parser::leerespacios(string cad)
{
    for(int i=0;i<cad.size();i++)
        if(isspace(cad.at(i)))
            espacios.push_back(i);
}

/** La funcion separar datos utiliza las funciones leerparentesis y leerespacios para inicializar los vectores
  * inicio, fin1, fin2 y espacios y así poder posicionarse e ir sacando la información entre dichas posiciones.
  * cada porcion de informacion que saque se lo enviara a la clase datos correspondiente (global, see o sense) y esta
  * lo almacenara segun corresponda*/

void Parser::separardatos(string cad, Datos &valor)
{
    string buffer,instruccion,dato; //Variable necesaria para poder buscar espacios, ya que tenemos un char y le pasamos un string.
    int i=0;
    int a,c; //Variables para manejar la posicion de inicio de lectura
    int b,d; //Variables para manejar la longitud de lectura
    int t;
    inicio.clear();
    fin1.clear();           //Borramos los vectores para evitar
    fin2.clear();           //posibles superposiciones de datos

    leerparentesis(cad);
    leerespacios(cad);

    if (cad.find("see")!=string::npos && cad.size()>15 ) /** Leemos la cadena see si es superior a 15 caracteres*/
    {
        if(cad.size()<10) cout<<"Cadena see corta"<<endl; //Si solo llega una instruccion de tipo (see xxxx) la deshechamos
        else
        {
            for(inicio.at(i);i<inicio.size();i++)/** Hago tantas lecturas como parentesis tenga */
            {
                a=fin1.at(i)-inicio.at(i)-1;
                b=inicio.at(i)+1;
                c=fin2.at(i)-fin1.at(i)-2;
                d=fin1.at(i)+2;
                char inst[a]; /** Almaceamos en cadena los terminos que indican de que instruccion se trata*/
                char data[c];
                bzero(inst,a+1);
                bzero(data,c+1);
                cad.copy(inst,a,b); /** Copiamos en cadena la instruccion que se comparara completa*/
                instruccion=inst;//LA INSTRUCCION SE PASARA CADA VEZ QUE ENVIEMOS UN DATO
                cad.copy(data,c,d);
                buffer.clear();
                buffer=data;
                espacios.clear();
                leerespacios(buffer);
                valor.valores.clear();
                for(int j=0;j<=espacios.size();j++)
                {
                    if (j==0)
                    {
                        t=espacios.at(j);
                        char dat[t]; /** Almaceamos en comando los terminos que indican de que instruccion se trata*/
                        bzero(dat,t+1);
                        buffer.copy(dat,t,0);
                        dato.clear();
                        dato=dat;
                        valor.setValor(dato); //Introducimos el valor en el vector
                    }

                    if (j==espacios.size())
                    {
                        t=buffer.size()-espacios.at(j-1);
                        char dat[t]; /** Almaceamos en comado el ultimo valor de la secuencia*/
                        bzero(dat,t+1);
                        buffer.copy(dat,t,espacios.at(j-1)+1);
                        dato.clear();
                        dato=dat;
                        valor.setValor(dato);//Introducimos el valor en el vector
                    }

                    if(j!=0 && j!=espacios.size())
                    {
                        t=espacios.at(j)-espacios.at(j-1)-1;
                        char dat[t]; /** Almaceamos en comando los valores intermedios*/
                        bzero(dat,t+1);
                        buffer.copy(dat,t,espacios.at(j-1)+1);
                        dato.clear();
                        dato=dat;
                        valor.setValor(dato); //Introducimos el valor en el vector
                    }
                }
                valor.setDatosSee (instruccion, valor.valores); //Introducimos en cada instrucción sus valores correspondientes
            }
        }
    }

    /** Almacenamos las cadenas de tipo sense body */

    if(cad.find("sense_body")!=string::npos)
    {
        for(inicio.at(i);i<inicio.size();i++)/** Hago tantas lecturas como parentesis tenga*/
        {
            if(fin1.size()==0) //Para instrucciones globales
                a=fin2.at(i)-inicio.at(i)-1;
            else
                a=fin1.at(i)-inicio.at(i)-1; //Para sense_body
            b=inicio.at(i)+1;
            char cadena[a]; /** Almaceamos en cadena los terminos que indican de que instruccion se trata*/
            bzero(cadena,a+1);
            cad.copy(cadena,a,b);
            buffer.clear();
            buffer=cadena;
            /** Buscamos los espacios y mandamos el comando a la clase de datos */
            espacios.clear();
            leerespacios(buffer);
            valor.valores.clear();
            for(int j=0;j<=espacios.size();j++)
            {
                if (j==0)
                {
                    t=espacios.at(j);
                    char inst[t]; /** Almaceamos en comando los terminos que indican de que instruccion se trata*/
                    bzero(inst,t+1);
                    buffer.copy(inst,t,0);
                    instruccion.clear();
                    instruccion=inst;
                }

                if (j==espacios.size())
                {
                    t=buffer.size()-espacios.at(j-1);
                    char dat[t]; /** Almaceamos en comado el ultimo valor de la secuencia*/
                    bzero(dat,t+1);
                    buffer.copy(dat,t,espacios.at(j-1)+1);
                    dato.clear();
                    dato=dat;
                    valor.setValor(dato); //Introducimos el valor en el vector
                }

                if(j!=0 && j!=espacios.size())
                {
                    t=espacios.at(j)-espacios.at(j-1)-1;
                    char dat[t]; /** Almaceamos en comando los valores intermedios*/
                    bzero(dat,t+1);
                    buffer.copy(dat,t,espacios.at(j-1)+1);
                    dato.clear();
                    dato=dat;
                    valor.setValor(dato); //Introducimos el valor en el vector
                }

            }
            valor.setDatosSense (instruccion,valor.valores); //Introducimos en cada instrucción sus valores correspondientes
        }
    }

    /** Almacenamos las cadenas de tipo hear */
    if(cad.find("hear")!=string::npos)
    {
        valor.valores.clear();
        a=espacios.at(2)-espacios.at(1)-1;
        b=espacios.at(1)+1;
        string who,inst,side;
        char cada[a]; /** Almaceamos en cada quien realiza el hear*/
        bzero(cada,a+1);
        cad.copy(cada,a,b);
        who.clear();
        who=cada;
        a=cad.size()-espacios.at(2)-4; //NO LEEMOS EL LADO
        b=espacios.at(2)+1;
        char cadb[a]; /** Almaceamos en cadb los terminos que indican de que instruccion se trata*/
        bzero(cadb,a+1);
        cad.copy(cadb,a,b);
        inst.clear();
        inst=cadb;
        valor.valores.push_back(inst);
        b=cad.size()-2;
        char cadc[1]; /** Almacenamos en cadb el lado de la instruccion */
        bzero(cadc,a+1);
        cad.copy(cadc,1,b);
        side.clear();
        side=cadc;
        valor.valores.push_back(side);
        valor.setDatosHear(who,valor.valores);
    }
    if(cad.find("init")!=string::npos)
    {
        valor.valores.clear();
        a=espacios.at(2)-espacios.at(1)-1;
        b=espacios.at(1)+1;
        string numero, side;
        char cadnumero[a];
        bzero(cadnumero,a+1);
        cad.copy(cadnumero,a,b);
        numero.clear();
        numero=cadnumero;
        valor.valores.push_back(numero);
        b=espacios.at(0)+1;
        char cadside[a];
        bzero(cadside,a+1);
        cad.copy(cadside,1,b);
        side.clear();
        side=cadside;
        valor.valores.push_back(side);
        valor.setInit(valor.valores);
    }
}
